package com.lfy.yunpicture.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lfy.yunpicture.api.aliyun.PictureAiApi;
import com.lfy.yunpicture.api.aliyun.model.CreateOutPaintingTaskRequest;
import com.lfy.yunpicture.api.aliyun.model.CreateOutPaintingTaskResponse;
import com.lfy.yunpicture.api.aliyun.model.GetOutPaintingTaskResponse;
import com.lfy.yunpicture.common.ErrorCode;
import com.lfy.yunpicture.constant.CommonConstant;
import com.lfy.yunpicture.exception.BusinessException;
import com.lfy.yunpicture.exception.ThrowUtils;
import com.lfy.yunpicture.manager.CosManager;
import com.lfy.yunpicture.manager.auth.SpaceUserAuthManager;
import com.lfy.yunpicture.manager.auth.StpKit;
import com.lfy.yunpicture.manager.auth.model.SpaceUserPermissionConstant;
import com.lfy.yunpicture.manager.filemanager.FileCommonManager;
import com.lfy.yunpicture.mapper.PictureMapper;
import com.lfy.yunpicture.model.dto.ai.PictureAiRequest;
import com.lfy.yunpicture.model.dto.file.*;
import com.lfy.yunpicture.model.entity.Picture;
import com.lfy.yunpicture.model.entity.Space;
import com.lfy.yunpicture.model.entity.User;
import com.lfy.yunpicture.model.enums.FileUploadBizEnum;
import com.lfy.yunpicture.model.enums.ReviewStatusEnum;
import com.lfy.yunpicture.model.enums.UserRoleEnum;
import com.lfy.yunpicture.model.vo.PictureMessageResponse;
import com.lfy.yunpicture.model.vo.PictureVO;
import com.lfy.yunpicture.model.vo.UserVO;
import com.lfy.yunpicture.service.PictureService;
import com.lfy.yunpicture.service.SpaceService;
import com.lfy.yunpicture.service.UserService;
import com.lfy.yunpicture.utils.SqlUtils;
import com.qcloud.cos.exception.CosClientException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 图片服务实现
 */
@Service
@Slf4j
public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture> implements PictureService {

    @Resource
    private UserService userService;
    @Resource
    private FileCommonManager fileCommonManager;
    @Resource
    private SpaceService spaceService;
    @Resource
    private CosManager cosManager;
    @Resource
    private TransactionTemplate transactionTemplate;
    @Resource
    private PictureAiApi pictureAiApi;
    @Resource
    private SpaceUserAuthManager spaceUserAuthManager;
    /**
     * 校验数据
     *
     * @param picture
     * @param add     对创建的数据进行校验
     */
    @Override
    public void validPicture(@NotNull Picture picture, boolean add) {
        //  从对象中取值
        String url = picture.getUrl();
        String name = picture.getName();
        String introduction = picture.getIntroduction();
        String category = picture.getCategory();
        String tags = picture.getTags();
        // 创建数据时，参数不能为空
        if (add) {
            //补充校验规则
            ThrowUtils.throwIf(StringUtils.isBlank(tags), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(StringUtils.isBlank(category), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(StringUtils.isBlank(introduction), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(StringUtils.isBlank(name), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(StringUtils.isBlank(url), ErrorCode.PARAMS_ERROR);
        }
        // 修改数据时，有参数则校验
        // 补充校验规则
        if (StringUtils.isNotBlank(name)) {
            ThrowUtils.throwIf(name.length() > 20, ErrorCode.PARAMS_ERROR, "图片名称过长");
        }
        if (StringUtils.isNotBlank(introduction)) {
            ThrowUtils.throwIf(introduction.length() > 30, ErrorCode.PARAMS_ERROR, "图片描述过长");
        }
    }

    /**
     * 获取查询条件
     *
     * @param pictureQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<Picture> getQueryWrapper(PictureQueryRequest pictureQueryRequest) {
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        if (pictureQueryRequest == null) {
            return queryWrapper;
        }
        // 从对象中取值
        Long id = pictureQueryRequest.getId();
        String url = pictureQueryRequest.getUrl();
        String name = pictureQueryRequest.getName();
        String introduction = pictureQueryRequest.getIntroduction();
        String category = pictureQueryRequest.getCategory();
        List<String> tags = pictureQueryRequest.getTags();
        String picFormat = pictureQueryRequest.getPicFormat();
        Long userId = pictureQueryRequest.getUserId();
        String sortField = pictureQueryRequest.getSortField();
        String sortOrder = pictureQueryRequest.getSortOrder();
        String searchText = pictureQueryRequest.getSearchText();
        Integer reviewStatus = pictureQueryRequest.getReviewStatus();
        Long spaceId = pictureQueryRequest.getSpaceId();
        Date startTime = pictureQueryRequest.getStartTime();
        Date endTime = pictureQueryRequest.getEndTime();
        //补充需要的查询条件
        // 从多字段中搜索
        if (StringUtils.isNotBlank(searchText)) {
            // 需要拼接查询条件
            queryWrapper.and(qw -> qw.like("name", searchText).or()
                    .like("introduction", searchText));
        }
        // 模糊查询
        queryWrapper.like(StringUtils.isNotBlank(name), "name", name);
        queryWrapper.like(StringUtils.isNotBlank(introduction), "introduction", introduction);
        // JSON 数组查询
        if (CollUtil.isNotEmpty(tags)) {
            for (String tag : tags) {
                queryWrapper.like("tags", "\"" + tag + "\"");
            }
        }
        // 精确查询
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        // 对于公共空间，查询条件为spaceId is null
        if (spaceId == null) {
            queryWrapper.isNull("spaceId");
        }
        queryWrapper.eq(ObjectUtils.isNotEmpty(spaceId), "spaceId", spaceId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(url), "url", url);
        queryWrapper.eq(ObjectUtils.isNotEmpty(category), "category", category);
        queryWrapper.eq(ObjectUtils.isNotEmpty(picFormat), "picFormat", picFormat);
        queryWrapper.eq(ObjectUtils.isNotEmpty(reviewStatus), "reviewStatus", reviewStatus);
        queryWrapper.ge(ObjectUtils.isNotEmpty(startTime), "createTime", startTime);
        queryWrapper.lt(ObjectUtils.isNotEmpty(endTime), "createTime", endTime);
        // 排序规则
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    /**
     * 获取图片封装
     *
     * @param picture
     * @param request
     * @return
     */
    @Override
    public PictureVO getPictureVO(Picture picture, HttpServletRequest request) {
        // 对象转封装类
        PictureVO pictureVO = PictureVO.objToVo(picture);
        // 可以根据需要为封装对象补充值，不需要的内容可以删除
        // region 可选
        // 1. 关联查询用户信息
        Long userId = picture.getUserId();
        User user = null;
        if (userId != null && userId > 0) {
            user = userService.getById(userId);
            ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "该用户不存在");
        }else{
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "创建用户ID为空");
        }
        UserVO userVO = userService.getUserVO(user);
        pictureVO.setUser(userVO);
        // 如果存在spaceId,那么需要权限才能获得
        Long spaceId = picture.getSpaceId();
        User loginUser = userService.getLoginUser(request);
        if(spaceId != null){
            Space space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(space == null, ErrorCode.PARAMS_ERROR, "空间不存在，上传失败");
            boolean b = StpKit.SPACE.hasPermission(SpaceUserPermissionConstant.PICTURE_VIEW);
            ThrowUtils.throwIf(!b, ErrorCode.NO_AUTH_ERROR);
            List<String> permissionList = spaceUserAuthManager.getPermissionList(space, loginUser);
            pictureVO.setPermissionList(permissionList);
        }else{
            // 如果是图片创建者或者是管理员，拥有图片的所有操作权限
            if (userId.equals(loginUser.getId()) || userService.isAdmin(loginUser)) {
                List<String> permissionList = Arrays.asList(SpaceUserPermissionConstant.PICTURE_VIEW, SpaceUserPermissionConstant.PICTURE_EDIT, SpaceUserPermissionConstant.PICTURE_DELETE, SpaceUserPermissionConstant.PICTURE_UPLOAD);
                pictureVO.setPermissionList(permissionList);
            }else{
                List<String> permissionList = Arrays.asList(SpaceUserPermissionConstant.PICTURE_VIEW);
                pictureVO.setPermissionList(permissionList);
            }
        }
        // endregion
        return pictureVO;
    }

    /**
     * 分页获取图片封装
     *
     * @param picturePage
     * @param request
     * @return
     */
    @Override
    public Page<PictureVO> getPictureVOPage(Page<Picture> picturePage, HttpServletRequest request) {
        List<Picture> pictureList = picturePage.getRecords();
        Page<PictureVO> pictureVOPage = new Page<>(picturePage.getCurrent(), picturePage.getSize(), picturePage.getTotal());
        if (CollUtil.isEmpty(pictureList)) {
            return pictureVOPage;
        }
        // 对象列表 => 封装对象列表
        List<PictureVO> pictureVOList = pictureList.stream().map(picture -> {
            return PictureVO.objToVo(picture);
        }).collect(Collectors.toList());

        // 可以根据需要为封装对象补充值，不需要的内容可以删除
        // region 可选
        // 1. 关联查询用户信息
        Set<Long> userIdSet = pictureList.stream().map(Picture::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        // 填充信息
        pictureVOList.forEach(pictureVO -> {
            Long userId = pictureVO.getUserId();
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            pictureVO.setUser(userService.getUserVO(user));
        });
        // endregion

        pictureVOPage.setRecords(pictureVOList);
        return pictureVOPage;
    }

    @Override
    public PictureVO uploadFile(MultipartFile multipartFile, UploadPictureRequest uploadPictureRequest, HttpServletRequest request) {
        // 校验登录态
        User loginUser = userService.getLoginUser(request);
        Picture picture = new Picture();
        valid(picture, uploadPictureRequest);
        PictureMessageResponse pictureMessageResponse = fileCommonManager.uploadFile(multipartFile, uploadPictureRequest, loginUser.getId());
        return getPictureVO(uploadPictureRequest, pictureMessageResponse, picture, loginUser);
    }

    @Override
    public PictureVO uploadFileUrl(UploadPictureRequest uploadPictureRequest, HttpServletRequest request) {
        // 校验登录态
        User loginUser = userService.getLoginUser(request);
        Picture picture = new Picture();
        valid(picture, uploadPictureRequest);
        PictureMessageResponse pictureMessageResponse = fileCommonManager.uploadFile(uploadPictureRequest.getUploadUrl(), uploadPictureRequest, loginUser.getId());
        return getPictureVO(uploadPictureRequest, pictureMessageResponse, picture, loginUser);
    }

    /**
     * 文件上传与Url上传公共校验方法
     *
     * @param picture
     * @param uploadPictureRequest
     */
    public void valid(Picture picture, UploadPictureRequest uploadPictureRequest) {
        Long uploadFileId = uploadPictureRequest.getUploadFileId();
        // 如果id不为空，先查询数据库看是否存在
        if (uploadFileId != null) {
            Picture pictureById = this.getById(uploadFileId);
            ThrowUtils.throwIf(pictureById == null, new BusinessException(ErrorCode.PARAMS_ERROR, "图片不存在，上传失败"));
            picture.setId(uploadFileId);
            picture.setEditTime(new Date());
            picture.setPicSize(pictureById.getPicSize());
            picture.setUrl(pictureById.getUrl());
            picture.setThumbnail(pictureById.getThumbnail());
        }
        // 如果空间ID不为空，查询数据库看是否存在
        Long spaceId = uploadPictureRequest.getSpaceId();
        if (spaceId != null) {
            Space space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(space == null, new BusinessException(ErrorCode.PARAMS_ERROR, "空间不存在，上传失败"));
            picture.setSpaceId(spaceId);
            // 审核通过
            picture.setReviewStatus(ReviewStatusEnum.PASS.getValue());
            picture.setReviewMessage("私有空间直接通过");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public PictureVO getPictureVO(UploadPictureRequest uploadPictureRequest, PictureMessageResponse pictureMessageResponse, Picture picture, User loginUser) {
        Long oldPicSize = picture.getPicSize();
        String url = picture.getUrl();
        String thumbnail = picture.getThumbnail();
        BeanUtil.copyProperties(pictureMessageResponse, picture);
        picture.setUserId(loginUser.getId());

        //如果是上传用户头像，直接返回
        if (FileUploadBizEnum.USER_AVATAR.getValue().equals(uploadPictureRequest.getBiz())) {
            return BeanUtil.copyProperties(picture, PictureVO.class);
        }
        // spaceId不为空，进行权限校验
        if(uploadPictureRequest.getSpaceId() != null){
            boolean hasPermission = StpKit.SPACE.hasPermission(SpaceUserPermissionConstant.PICTURE_UPLOAD);
            ThrowUtils.throwIf(!hasPermission, ErrorCode.NO_AUTH_ERROR);
        }
        // 如果spaceId为空
        if (uploadPictureRequest.getSpaceId() == null) {
            // 如果是普通用户上传图片，需要重置审核状态
            if (UserRoleEnum.USER.getValue().equals(loginUser.getUserRole())) {
                picture.setReviewStatus(ReviewStatusEnum.WAIT_REVIEW.getValue());
            } else {
                // 管理员直接通过
                picture.setReviewStatus(ReviewStatusEnum.PASS.getValue());
                picture.setReviewMessage("管理员直接通过");
            }
        }
        //修改数据库,如果存在就修改，不存在就新增
        Long spaceId = picture.getSpaceId();
        // 如果是新增
        if (picture.getId() == null) {
            boolean save = this.save(picture);
            ThrowUtils.throwIf(!save, new BusinessException(ErrorCode.OPERATION_ERROR));
            // 如果spaceId不为空，修改数据库表
            if (spaceId != null) {
                // 判断是否超额
                Space spaceById = spaceService.getById(spaceId);
                if (spaceById.getTotalSize() + picture.getPicSize() > spaceById.getMaxSize() || spaceById.getTotalCount() + 1 > spaceById.getMaxCount()) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "空间容量不足，上传失败");
                }
                // 修改数据库
                boolean update = spaceService.lambdaUpdate()
                        .eq(Space::getId, spaceId)
                        .setSql("totalCount = totalCount +1")
                        .setSql("totalSize = totalSize +" + picture.getPicSize())
                        .update();
                ThrowUtils.throwIf(!update, new BusinessException(ErrorCode.OPERATION_ERROR));
            }
        }
        // 如果是修改
        else {
            boolean b = this.updateById(picture);
            ThrowUtils.throwIf(!b, new BusinessException(ErrorCode.OPERATION_ERROR));
            // 如果spaceId不为空，修改数据库表
            if (spaceId != null) {
                // 用新的大小，减去旧的大小
                long size = picture.getPicSize() - oldPicSize;
                // 判断是否超额
                Space spaceById = spaceService.getById(spaceId);
                if (spaceById.getTotalSize() + size > spaceById.getMaxSize()) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "空间容量不足，上传失败");
                }
                boolean update = spaceService.lambdaUpdate()
                        .eq(Space::getId, spaceId)
                        .setSql("totalSize = totalSize +" + size)
                        .update();
                ThrowUtils.throwIf(!update, new BusinessException(ErrorCode.OPERATION_ERROR));
            }
            // 删除旧的cos对象
            try {
                cosManager.deleteObject(url, thumbnail);
            } catch (CosClientException e) {
                log.error("cos file delete error", e);
            }
        }
        PictureVO pictureVO = PictureVO.objToVo(picture);
        pictureVO.setUser(userService.getUserVO(loginUser));
        return pictureVO;
    }

    /**
     * 图片批量上传
     *
     * @param pictureBatchUploadRequest
     * @param request
     * @return
     */
    @Override
    public Integer pictureBatchUpload(PictureBatchUploadRequest pictureBatchUploadRequest, HttpServletRequest request) {
        Integer pictureNum = pictureBatchUploadRequest.getPictureNum();
        String searchText = pictureBatchUploadRequest.getSearchText();
        String picturePrefix = pictureBatchUploadRequest.getPicturePrefix();
        User loginUser = userService.getLoginUser(request);
        // 限制抓取的数量最多为30
        ThrowUtils.throwIf(pictureNum > 30, ErrorCode.PARAMS_ERROR, "最多搜索30张图片");
        // 从数据库查询包含了搜索关键字的图片有多少
        Long number = this.lambdaQuery()
                .like(StrUtil.isNotBlank(searchText), Picture::getName, searchText)
                .count();
        if (number == 0) {
            number = 1L;
        }
        // 请求地址
        String format = String.format("https://cn.bing.com/images/search?q=%s&first=%s&mmasync=1", searchText, number);
        Document document = null;
        // 抓取图片
        try {
            document = Jsoup.connect(format).get();
        } catch (IOException e) {
            log.error("连接失败", e);
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "连接失败");
        }
        Element dgController = document.getElementsByClass("dgControl").first();
        if (ObjectUtil.isEmpty(dgController)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "获取文档失败");
        }
        Elements elements = dgController.select("img.mimg");
        if (CollUtil.isEmpty(elements)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "图片列表为空");
        }
        // 用于计算图片数量
        int count = 0;
        for (Element element : elements) {
            // 取得图片地址
            String src = element.attr("src");
            if (StrUtil.isBlank(src)) {
                log.info("当前图片地址为空：{}", src);
                continue;
            }
            // 处理图片地址
            int indexOf = src.indexOf("?");
            if (indexOf != -1) {
                src = src.substring(0, indexOf);
            }
            // 上传文件
            try {
                UploadPictureRequest uploadPictureRequest = new UploadPictureRequest();
                PictureMessageResponse pictureMessage = fileCommonManager.uploadFile(src, uploadPictureRequest, loginUser.getId());
                if (StrUtil.isBlank(picturePrefix)) {
                    picturePrefix = searchText;
                }
                //修改数据库
                Picture picture = new Picture();
                BeanUtil.copyProperties(pictureMessage, picture);
                picture.setUserId(loginUser.getId());
                picture.setName(picturePrefix + number++);
                picture.setReviewStatus(ReviewStatusEnum.PASS.getValue());
                picture.setReviewMessage("管理员直接通过");
                picture.setCategory("其他");
                boolean save = this.save(picture);
                // 如果数据库操作失败，直接返回
                if (!save) {
                    return count;
                }
                count++;
            } catch (Exception e) {
                log.error("图片上传失败：{}", e);
                continue;
            }
            if (count >= pictureNum) {
                break;
            }
        }
        return count;
    }

    @Override
    public void validSpaceId(Long spaceId) {
        if (spaceId != null) {
            // 查询数据库是否存在
            Space space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
        }
    }

    @Override
    public void deletePicture(Long id, HttpServletRequest request) {
        User user = userService.getLoginUser(request);
        // 判断是否存在
        Picture oldPicture = this.getById(id);
        ThrowUtils.throwIf(oldPicture == null, ErrorCode.NOT_FOUND_ERROR);
//        // 仅本人或管理员可删除
//        if (!oldPicture.getUserId().equals(user.getId()) && !userService.isAdmin(request)) {
//            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
//        }
        transactionTemplate.execute(status -> {
            // 操作数据库
            boolean result = this.removeById(id);
            ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
            // 如果spaceId不为空，更新空间额度
            Long spaceId = oldPicture.getSpaceId();
            if (spaceId != null) {
                boolean update = spaceService.lambdaUpdate()
                        .eq(Space::getId, spaceId)
                        .setSql("totalSize = totalSize -" + oldPicture.getPicSize())
                        .setSql("totalCount = totalCount -1")
                        .update();
                ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR);
            }
            return null;
        });
        // 删除cos对象存贮文件
        try {
            cosManager.deleteObject(oldPicture.getUrl(), oldPicture.getThumbnail());
        } catch (CosClientException e) {
            log.error("cos file delete error", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePictureBatch(List<Long> ids) {
        // 删除cos对象存贮文件
        int sumSize = 0;
        Long spaceId = null;
        for (Long id : ids) {
            Picture picture = this.getById(id);
            if (picture != null) {
                spaceId = picture.getSpaceId();
                try {
                    cosManager.deleteObject(picture.getUrl(), picture.getThumbnail());
                } catch (CosClientException e) {
                    log.error("cos file delete error", e);
                    throw new BusinessException(ErrorCode.OPERATION_ERROR);
                }
                sumSize += picture.getPicSize();
            } else {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "图片不存在");
            }
        }
        // 删除图片
        boolean result = this.removeBatchByIds(ids);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        // 更新空间额度
        boolean update = spaceService.lambdaUpdate()
                .eq(Space::getId, spaceId)
                .setSql("totalSize = totalSize -" + sumSize)
                .setSql("totalCount = totalCount -" + ids.size())
                .update();
        ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR);
    }

    @Override
    public void editPicture(PictureEditRequest pictureEditRequest, HttpServletRequest request) {
        //在此处将实体类和 DTO 进行转换
        Picture picture = new Picture();
        BeanUtils.copyProperties(pictureEditRequest, picture);
        picture.setTags(JSONUtil.toJsonStr(pictureEditRequest.getTags()));
        picture.setEditTime(new Date());
        // 数据校验
        this.validPicture(picture, false);
        User loginUser = userService.getLoginUser(request);
        // 判断是否存在
        long id = pictureEditRequest.getId();
        Picture oldPicture = this.getById(id);
        ThrowUtils.throwIf(oldPicture == null, ErrorCode.NOT_FOUND_ERROR);
//        // 仅本人或管理员可编辑
//        if (!oldPicture.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
//            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
//        }
        // 如果是普通用户编辑图片，需要重置审核状态
        if (UserRoleEnum.USER.getValue().equals(loginUser.getUserRole())) {
            picture.setReviewStatus(ReviewStatusEnum.WAIT_REVIEW.getValue());
        } else {
            picture.setReviewStatus(ReviewStatusEnum.PASS.getValue());
        }
        // 操作数据库
        boolean result = this.updateById(picture);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
    }

    @Override
    public CreateOutPaintingTaskResponse.Output aiExpansion(PictureAiRequest aiRequest) {
        // 参数检验
        String pictureId = aiRequest.getPictureId();
        ThrowUtils.throwIf(StringUtils.isBlank(pictureId), new BusinessException(ErrorCode.PARAMS_ERROR, "图片id不能为空"));
        // 判断图片是否存在
        Picture picture = this.getById(pictureId);
        ThrowUtils.throwIf(picture == null, new BusinessException(ErrorCode.NOT_FOUND_ERROR, "图片不存在"));
        // 调用图片扩图服务
        CreateOutPaintingTaskRequest createOutPaintingTaskRequest = new CreateOutPaintingTaskRequest();
        createOutPaintingTaskRequest.setParameters(aiRequest.getParameters());
        createOutPaintingTaskRequest.setInput(new CreateOutPaintingTaskRequest.Input(picture.getUrl()));
        return pictureAiApi.createOutPaintingTask(createOutPaintingTaskRequest).getOutput();
    }

    @Override
    public GetOutPaintingTaskResponse getOutPaintingTask(String taskId) {
        return pictureAiApi.getOutPaintingTask(taskId);
    }

    @Override
    public long addPicture(PictureAddRequest pictureAddRequest, HttpServletRequest request) {
        Long spaceId = pictureAddRequest.getSpaceId();
        if(spaceId != null){
            Space space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
            boolean b = StpKit.SPACE.hasPermission(SpaceUserPermissionConstant.PICTURE_UPLOAD);
            ThrowUtils.throwIf(!b, ErrorCode.NO_AUTH_ERROR);
        }
        //  在此处将实体类和 DTO 进行转换
        Picture picture = new Picture();
        BeanUtils.copyProperties(pictureAddRequest, picture);
        picture.setTags(JSONUtil.toJsonStr(pictureAddRequest.getTags()));
        // 将图片信息添加到实体类中
        PictureVO pictureVO = pictureAddRequest.getPictureVO();
        if (pictureVO != null) {
            picture.setUrl(pictureVO.getUrl());
            picture.setPicFormat(pictureVO.getPicFormat());
            picture.setPicHeight(pictureVO.getPicHeight());
            picture.setPicWidth(pictureVO.getPicWidth());
            picture.setPicScale(pictureVO.getPicScale());
            picture.setPicSize(pictureVO.getPicSize());
            picture.setId(pictureVO.getId());
            picture.setEditTime(new Date());
        }
        // 数据校验
        this.validPicture(picture, true);
        //填充默认值
        User loginUser = userService.getLoginUser(request);
        picture.setUserId(loginUser.getId());
        // 写入数据库
        boolean result = this.saveOrUpdate(picture);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        // 返回新写入的数据 id
        return picture.getId();
    }

}
